﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using mojoPortal.Web;
using blackhouse.BlackApart.Business.Apartments;
using blackhouse.BlackApart.Business;
using blackhouse.Aparts.Web.Modules;
using blackhouse.BlackApart.Web;
using blackhouse.BlackApart.Business.Prices;
using blackhouse.JavaScript.JQuery;
using blackhouse.BlackApart.Business.Reservations;
using System.IO;
using blackhouse.Web;
using blackhouse.BlackApart.Business.Cities;
using blackhouse.mojoPortalExtend.Breadcrumbs;
using mojoPortal.Business;

namespace blackhouse.Aparts.Web.Pages {
    public partial class Apartments : NonCmsBasePage {

        #region Fields

        private Factory factory;
        private SearchState queryState = SearchState.GetFromContext();
        private IApartmentGroup[] groups;
        private FreeApartments search;
        private string rightUrl;
        private SiteCity city;
        private blackhouse.mojoPortalExtend.PageProvider apartmentsPage;
        private BreadcrumbsAccess breadcrumbs;

        #endregion

        #region Event Handlers

        protected override void OnPreInit(EventArgs e) {
            this.AllowSkinOverride = true;
            HttpContext.Current.Items.Add("skin", "blackhouse");
            HttpContext.Current.Items.Add("short-top", true);


            base.OnPreInit(e);
        }

        protected override void OnInit(EventArgs e) {
            base.OnInit(e);
            this.AddClassToBody("short-top");
            this.rptApartments.ItemDataBound += new RepeaterItemEventHandler(rptApartments_ItemDataBound);
            this.factory = Factory.Instance();

            this.city = factory.GetSiteCity();
            this.rightUrl = "/" + GetGlobalResourceObject("Aparts", "apartmentsUrl");
            this.rightUrl = this.rightUrl + '-' + city.UrlName;
            this.RedirectIfInvalid();
        }

        private void SetInstance() {

            this.breadcrumbs = new BreadcrumbsAccess();
            this.apartmentsPage = new mojoPortalExtend.PageProvider();
            if (this.queryState.IsSet) {
                this.search = new FreeApartments(this.queryState.ArrivalDate, this.queryState.DepartureDate, this.queryState.PeopleCount);

                if (this.search.Count() > 0) {
                    List<IApartmentGroup> gr = new List<IApartmentGroup>();
                    for (int xv = 0; xv < this.search.Count(); xv++) {
                        gr.Add(new ApartmentGroupWithVariant(
                        this.search.ElementAt(xv).GetGroups().OrderByDescending(g => g.NumberOfPeople).First(),
                        this.search.ElementAt(xv)));
                    }
                    this.groups = gr.ToArray();
                }
                else this.groups = new IApartmentGroup[0];
            }
            else {
                this.groups = factory.GetApartmentGroup().GetAllApartmentTypes();
                //this.SetPrices();
            }
        }

        private void RedirectIfInvalid() {
            if (Request["rewritetorighturl"] == "true") {

                string[] urlParts = Request.RawUrl.Split('?');

                if (!urlParts[0].EndsWith(rightUrl)) {
                    string url = UrlUtils.LocalizeUrl(rightUrl);
                    if (urlParts.Length > 1)
                        url = url + '?' + urlParts[1];
                    Response.RedirectPermanent(url);
                }
            }
        }

        private void SetPageSeo() {
            if (!this.apartmentsPage.TrySetFromCmsUrl("~/apartments")) {
                this.apartmentsPage.SetPageTitle("Lista apartamentów w {0}");
            }
            this.apartmentsPage.SetCanonicalUrl(Request.Url.GetLeftPart(UriPartial.Authority) + UrlUtils.LocalizeUrl(this.rightUrl));
            this.apartmentsPage.FormatPageTitle(this.city.SentenceName.ToFirstUpperString());
        }

        private void SetBreadcrumbs() {
            PageSettings ps = this.apartmentsPage.FindCmsPage("~/apartments");
            if (ps != null)
                this.breadcrumbs.AddCrumb(string.Format(ps.PageName, this.city.SentenceName.ToFirstUpperString()),
                    UrlUtils.LocalizeUrl("/" + HttpContext.GetGlobalResourceObject("Aparts", "apartmentsUrl") + '-' + this.city.UrlName));
        }

        private Dictionary<int, double> GetPromoPrices() {
            Dictionary<int, double> prices = new Dictionary<int, double>();
            foreach (IApartmentGroup group in groups) {
                IApartmentPrice p = factory.GetApartmentGroupPrice(group);

                double price = 0;
                if (this.queryState.IsSet) {
                    p.ReservationFromDay = this.queryState.ArrivalDate;
                    p.ReservationToDay = this.queryState.DepartureDate;
                    p.ReservationNumberOfPeoples = this.queryState.PeopleCount;
                    price = p.GetPricePerNight();
                }
                else
                    price = p.GetPromoPriceFrom(group);
                prices.Add(group.Id, price);
            }
            return prices;
        }

        private object GetRepeaterDataSource() {
            if (groups.Length > 1) {
                IEnumerable<IApartmentGroup> g = this.bhSorter.Sort(groups);
                return g;
            }
            else
                return groups;
        }

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);

            if (!IsPostBack) {
                this.SetInstance();

                this.AddClassToBody("loader");

                this.bhSorter.AddSorter("price", "Cena", SortByPrice, BlackApart.Business.ApartmentSortModel.SortDirection.Asc);

                this.rptApartments.DataSource = this.GetRepeaterDataSource();
                this.rptApartments.DataBind();

                if (this.rptApartments.Items.Count == 0)
                    this.pnlNoFree.Visible = true;

                if (this.queryState.IsSet) {
                    if (this.queryState.IsLastMinute)
                        this.ltlTitleLastMinute.Visible = true;
                    else
                        this.ltlTitleSet.Visible = true;
                }
                else
                    this.ltlTitleNotSet.Visible = true;

                if (Request.QueryString["mod"] == "nofree")
                    this.pnlNoFreeMode.Visible = true;
                this.SetBreadcrumbs();
            }

        }

        protected override void OnLoadComplete(EventArgs e) {
            base.OnLoadComplete(e);
            this.SetPageSeo();
        }

        #endregion

        #region Methods

        void rptApartments_ItemDataBound(object sender, RepeaterItemEventArgs e) {
            switch (e.Item.ItemType) {
                case ListItemType.AlternatingItem:
                case ListItemType.Item:
                    IApartmentGroup group = e.Item.DataItem as IApartmentGroup;
                    ApartmentGroupWithVariant groupWithVariant = group as ApartmentGroupWithVariant;
                    Panel pnlHolder = e.Item.FindControl("pnlHolder") as Panel;
                    if (group != null && pnlHolder != null) {
                        ApartmentGroupLine line = this.Page.LoadControl("~/Modules/ApartmentGroupLine.ascx") as ApartmentGroupLine;
                        pnlHolder.Controls.Add(line);

                        if (group != null && line != null) {
                            if (groupWithVariant != null)
                                line.PopulateControl(group, groupWithVariant.Variant);
                            else
                                line.PopulateControl(group);
                        }
                        else
                            e.Item.Visible = false;
                    }
                    break;
            }
        }

        protected IEnumerable<IApartmentGroup> SortByPrice(IEnumerable<IApartmentGroup> groups) {
            if (this.queryState.IsSet) {
                return groups.Cast<ApartmentGroupWithVariant>().OrderBy(gv => gv.Variant.Price.GetPrice());
            }
            else {
                Dictionary<int, double> prices = this.GetPromoPrices();
                var q = from g in this.groups
                        join p in prices on g.Id equals p.Key
                        orderby p.Value
                        select g;
                return q;
            }
        }

        #endregion

    }
}
